home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Atari Compendium
/
The Atari Compendium (Toad Computers) (1994).iso
/
files
/
umich
/
falcon
/
programm.ing
/
asm56.zoo
/
a56.y
< prev
next >
Wrap
Text File
|
1992-11-14
|
39KB
|
1,754 lines
%{
/*******************************************************
*
* a56 - a DSP56001 assembler
*
* Written by Quinn C. Jensen
* July 1990
* jensenq@npd.novell.com (or jensenq@qcj.icon.com)
*
*******************************************************\
/*
* Copyright (C) 1990-1992 Quinn C. Jensen
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. The author makes no representations
* about the suitability of this software for any purpose. It is
* provided "as is" without express or implied warranty.
*
*/
/*
* a56.y - The YACC grammar for the assembler.
*
* Note: This module requires a "BIG" version of YACC. I had to
* recompile YACC in the largest mode available.
*
* Other notes:
*
* MOVEC, MOVEM and MOVEP must be used explicitly--MOVE can't yet figure
* out which form to use.
*
*/
#include "a56.h"
unsigned int w0, w1, pc;
extern BOOL list_on;
BOOL uses_w1;
int just_rep = 0;
extern char inline[];
char *spaces(), *luntab();
char segs[] = "PXYL";
int seg;
int substatement = 0;
BOOL long_symbolic_expr = FALSE;
struct n binary_op();
struct n unary_op();
struct n sym_ref();
#define R_R6 0x0001
#define R_R5 0x0002
#define R_R4 0x0004
#define R_DATA_ALU_ACCUM 0x0008
#define R_CTL_REG 0x0010
#define R_FUNKY_CTL_REG 0x0020
#define R_SDX 0x0040
#define R_SDY 0x0080
#define R_LSD 0x0100
#define R_AB 0x0200
#define R_XREG 0x0400
#define R_YREG 0x0800
/* registers to which short immediate move is an unsigned int */
#define R_UINT 0x1000
/* registers to which short immediate move is an signed frac */
#define R_SFRAC 0x2000
%}
%union {
int ival; /* integer value */
struct n n; /* just like in struct sym */
double dval; /* floating point value */
char *sval; /* string */
int cval; /* character */
char cond; /* condition */
struct regs {
int r6, r5, r4, data_alu_accum, ctl_reg, funky_ctl_reg;
int sdx, sdy, lsd, ab, xreg, yreg;
int flags;
} regs;
struct ea {
int mode;
int ext;
int pp;
} ea;
}
%token <n> CHEX CDEC FRAC
%token <ival> AREG BREG MREG NREG RREG XREG YREG
%token <ival> OP OPA OPP
%token <cond> OP_JCC OP_JSCC OP_TCC
%token <sval> SYM
%token <sval> STRING
%token <cval> CHAR
%token COMMENT
%token XMEM
%token YMEM
%token LMEM
%token PMEM
%token AAAA
%token A10
%token BBBB
%token B10
%token AABB
%token BBAA
%token XXXX
%token YYYY
%token SR
%token MR
%token CCR
%token OMR
%token SP
%token SSH
%token SSL
%token LA
%token LC
%token EOL
%token EOS
%token OP_ABS
%token OP_ADC
%token OP_ADD
%token OP_ADDL
%token OP_ADDR
%token OP_ASL
%token OP_ASR
%token OP_CLR
%token OP_CMP
%token OP_CMPM
%token OP_DIV
%token OP_MAC
%token OP_MACR
%token OP_MPY
%token OP_MPYR
%token OP_NEG
%token OP_NORM
%token OP_RND
%token OP_SBC
%token OP_SUB
%token OP_SUBL
%token OP_SUBR
%token OP_TFR
%token OP_TST
%token OP_AND
%token OP_ANDI
%token OP_EOR
%token OP_LSL
%token OP_LSR
%token OP_NOT
%token OP_OR
%token OP_ORI
%token OP_ROL
%token OP_ROR
%token OP_BCLR
%token OP_BSET
%token OP_BCHG
%token OP_BTST
%token OP_DO
%token OP_ENDDO
%token OP_LUA
%token OP_MOVE
%token OP_MOVEC
%token OP_MOVEM
%token OP_MOVEP
%token OP_ILLEGAL
%token OP_INCLUDE
%token OP_JMP
%token OP_JCLR
%token OP_JSET
%token OP_JSR
%token OP_JSCLR
%token OP_JSSET
%token OP_NOP
%token OP_REP
%token OP_RESET
%token OP_RTI
%token OP_RTS
%token OP_STOP
%token OP_SWI
%token OP_WAIT
%token OP_EQU
%token OP_ORG
%token OP_DC
%token OP_END
%token OP_PAGE
%token OP_PSECT
%token OP_ALIGN
%token SHL
%token SHR
%type <n> num num_or_sym
%type <n> num_or_sym_expr
%type <n> expr
%type <n> ix
%type <n> ix_long
%type <ival> abs_addr abs_short_addr io_short_addr
%type <ival> a_b x_or_y ea b5_10111_max
%type <ival> p6_ean_a6 ea_no_ext p6_ea_a6 ea_a6 ea_a12
%type <ival> ea_no_ext
%type <ival> ea_short
%type <ival> prog_ctl_reg
%type <ival> op8_1 op8_2 op8_3 op8_4 op8_5 op8_6 op8_7 op8_8
%type <ival> mpy_arg mpy_srcs plus_minus
%type <ival> sd3
%type <ival> funky_ctl_reg tcc_sd space
%type <regs> regs
%type <ea> movep_ea_pp
%left '|'
%left '^'
%left SHL SHR
%left '&'
%left '+' '-'
%left '*' '/' '%'
%right '~'
%start input
%%
/*%%%********************* top syntax ***********************/
input : /* empty */
| input statement
;
statement
: good_stuff EOL
{substatement = 0;
if(NOT check_psect(seg, pc) && pass == 2)
yyerror("%04X: psect violation", pc);
}
| good_stuff EOS
{substatement++;
if(NOT check_psect(seg, pc) && pass == 2)
yyerror("%04X: psect violation", pc);
}
| error
;
good_stuff
: /* empty */
{if(pass == 2 && list_on) {
printf("\n");
}}
| cpp_droppings
| COMMENT
{if(pass == 2 && NOT substatement && list_on) {
printf("%s%s\n", spaces(0), luntab(inline));
}}
| assembler_ops comment_field
{long_symbolic_expr = FALSE;}
| label_field operation_field comment_field
{char *printcode();
if(pass == 2) {
gencode(seg, pc, w0);
if(list_on) printf("%c:%04X %s %s\n", segs[seg], pc,
printcode(w0), substatement ? "" :
luntab(inline));
pc++;
if(uses_w1) {
gencode(seg, pc, w1);
if(list_on) printf("%c:%04X %s\n", segs[seg], pc,
printcode(w1 & 0xFFFFFF));
pc++;
}
} else {
pc++;
if(uses_w1)
pc++;
}
w0 = w1 = 0; uses_w1 = FALSE;
long_symbolic_expr = FALSE;}
| SYM comment_field
{sym_def($1, INT, pc);
free($1);
if(pass == 2) {
if(list_on) printf("%c:%04X%s%s\n", segs[seg], pc,
spaces(14-8), substatement ? "" :
luntab(inline));
long_symbolic_expr = FALSE;
}}
;
cpp_droppings
: '#' num STRING
{if(strlen($3) > 0)
curfile = $3;
curline = $2.val.i - 2;}
;
assembler_ops
: SYM OP_EQU expr
{sym_def($1, $3.type, $3.val.i, $3.val.f);
free($1);
if(pass == 2 && list_on) {
if($3.type == INT)
printf("%06X%s",
$3.val.i & 0xFFFFFF,
spaces(14-6-2));
else
printf("%10g%s", $3.val.f,
spaces(14-10-2));
printf("%s\n",
substatement ? "" : luntab(inline));
}}
| OP_ALIGN expr
{int ival = n2int($2);
if($2.type == UNDEF) {
yyerror("illegal forward reference");
} else if (ival <= 1) {
yyerror("%d: illegal alignment", ival);
} else {
if(pc % ival != 0)
pc += ival - pc % ival;
}
if(pass == 2 && list_on)
printf("%c:%04X%s%s\n", segs[seg], pc,
spaces(14-8), substatement ? "" : luntab(inline));
}
| OP_PSECT SYM
{struct psect *pp = find_psect($2);
if(NOT pp) {
if(pass == 2)
yyerror("%s: undefined psect", $2);
} else {
seg = pp->seg;
pc = pp->pc;
set_psect(pp);
if(pass == 2 && list_on)
printf("%c:%04X%s%s\n", segs[seg], pc,
spaces(14-8), substatement ? "" : luntab(inline));
}
free($2);}
| OP_PSECT SYM space expr ':' expr
{new_psect($2, $3, n2int($4), n2int($6));
if(pass == 2 && list_on)
printf("%c:%04X %04X%s%s\n",
segs[$3], n2int($4), n2int($6), spaces(14-8+4+1),
substatement ? "" : luntab(inline));
}
| OP_ORG space expr
{pc = n2int($3);
seg = $2;
if(pass == 2 && list_on)
printf("%c:%04X%s%s\n", segs[seg], pc,
spaces(14-8), substatement ? "" : luntab(inline));
}
| OP_ORG space expr ',' space expr
{pc = n2int($3);
seg = $2;
if(pass == 2 && list_on)
printf("%c:%04X%s%s\n", segs[seg], pc,
spaces(14-8), substatement ? "" : luntab(inline));
}
| label_field OP_DC dc_list
| OP_PAGE num ',' num ',' num ',' num
{if(pass == 2 && NOT substatement && list_on) {
printf("%s%s\n", spaces(0), luntab(inline));
}}
| OP_INCLUDE STRING
{if(pass == 2 && NOT substatement && list_on) {
printf("%s%s\n", spaces(0), luntab(inline));
}
include($2); /* free($2); */
}
| OP_END
{if(pass == 2 && NOT substatement && list_on) {
printf("%s%s\n", spaces(0), luntab(inline));
}}
;
dc_list
: dc_list ',' dc_stuff
| dc_stuff
;
dc_stuff
: STRING
{int len = strlen($1), i; char *cp; w0 = 0;